.TH "server" 3 "Fri Apr 15 2016" "Version 0.10.0-146_trunk" "libnetconf" \" -*- nroff -*-
.ad l
.nh
.SH NAME
server \- Server 

.SH "Server Architecture"
.PP
It is \fBstrongly\fP advised to set SUID (or SGID) bit on every application that is built on libnetconf for a user (or group) created for this purpose, as several internal functions behaviour is based on this precondition\&. libnetconf uses a number of files which pose a security risk if they are accessible by untrustworthy users\&. This way it is possible not to restrict the use of an application but only the access to its files, so keep this in mind when creating any directories or files that are used\&.
.PP
Generally, there are three approaches of how to implement a NETCONF server using libnetconf\&. The order in which they are mentioned is ascending in their implementation complexity\&. The use of the first single-level architecture for production environment is discouraged\&.
.SS "Single-level Architecture"
.PP
In this case, all the server functionality is implemented as a single process\&. It is started by SSH daemon as its Subsystem for each incoming NETCONF session connection\&. The main issue of this approach is a simultaneous access to shared resources\&. The device manager has to solve concurrent access to the controlled device from its multiple instances\&. libnetconf itself has to deal with simultaneous access to a shared configuration datastore\&.
.SS "Multi-level Architecture"
.PP
In the second case, there is only one device manager (NETCONF server) running as a system daemon\&. This solves the problem of concurrent device access from multiple processes\&. On the other hand, there is a need for inter-process communication between the device manager and the agents launched as SSH Subsystems\&. These agents hold NETCONF sessions and receive requests from the clients\&. libnetconf provides functions (\fBnc_rpc_dump()\fP and \fBnc_rpc_build()\fP) to (de-)serialise content of the NETCONF messages\&. This allows the NETCONF messages to be passed between an agent and a device manager that applies requests to the operated device and a configuration datastore\&.
.SS "Integrated Architecture"
.PP
In this last case, there is only a single application running having the SSH transport integrated\&. This way there is no need for any communication to other processes, which can be substituted by threads\&. At the cost of significantly increasing the complexity of the server and likely requiring additional libraries, it gains full control over client connections including the transport layer and dependencies on any external applications are removed\&. This is especially convenient for TLS, which in effect makes this architecture the only viable option that fully supports it\&.
.SH "Server Workflow"
.PP
Here is a description of using libnetconf functions in a NETCONF server\&. According to the used architecture, the workflow can be split between an agent and a server\&. For this purpose, functions \fBnc_rpc_dump()\fP, \fBnc_rpc_build()\fP and \fBnc_session_dummy()\fP can be very helpful\&.
.PP
.IP "1." 4
\fBSet the verbosity\fP (optional)
.br
The verbosity of the libnetconf can be set by \fBnc_verbosity()\fP\&. By default, libnetconf is completely silent\&.
.br
There is a default message printing function writing messages on stderr\&. On the server side, this is not very useful, since server usually runs as a daemon without stderr\&. In this case, something like syslog should be used\&. The application's specific message printing function can be set via \fBnc_callback_print()\fP function\&.
.IP "2." 4
\fBInitiate libnetconf\fP
.br
As the first step, libnetconf MUST be initiated using \fBnc_init()\fP\&. At this moment, the libnetconf subsystems, such as NETCONF Notifications or NETCONF Access Control, are initiated according to the specified parameter of the \fBnc_init()\fP function\&.
.IP "3." 4
\fBSet With-defaults basic mode\fP (optional)
.br
By default, libnetconf uses \fIexplicit\fP basic mode of the with-defaults capability\&. The basic mode can be changed via \fBncdflt_set_basic_mode()\fP function\&. libnetconf supports \fIexplicit\fP, \fItrim\fP, \fIreport-all\fP and \fIreport-all-tagged\fP basic modes of the with-defaults capability\&.
.IP "4." 4
\fBInitiate datastore\fP
.br
Now, a NETCONF datastore(s) can be created\&. Each libnetconf's datastore is connected with a single configuration data model\&. This connection is defined by calling the \fBncds_new()\fP function, which returns a datastore handler for further manipulation with an uninitialized datastore\&. Using this function, caller also specifies which datastore implementation type will be used\&. Optionally, some implementation-type-specific parameters can be set (e\&.g\&. \fBncds_file_set_path()\fP)\&. Finally, datastore must be initiated by \fBncds_init()\fP that returns datastore's ID which is used in the subsequent calls\&. There is a set of special implicit datastores with ID \fBNCDS_INTERNAL_ID\fP that refer to the libnetconf's internal datastore(s)\&.
.br
Optionally, each datastore can be extended by an augment data model that can be specified by \fBncds_add_model()\fP\&. The same function can be used to specify models to resolve YANG's \fCimport\fP statements\&. Alternatively, using \fBncds_add_models_path()\fP, caller can specify a directory where such models can be found automatically\&. libnetconf searches for the needed models based on the modules names\&. Filename of the model is expected in a form \fCmodule_name[@revision]\&.yin\fP\&.
.br
Caller can also switch on or off the YANG \fCfeauters\fP in the specific module using \fBncds_feature_enable()\fP, \fBncds_feature_disable()\fP, \fBncds_features_enableall()\fP and \fBncds_features_disableall()\fP functions\&.
.br
Finally, \fBncds_consolidate()\fP must be called to check all the internal structures and to solve all \fCimport\fP, \fCuses\fP and \fCaugment\fP statements\&.
.IP "5." 4
\fBInitiate the controlled device\fP
.br
This step is actually out of the libnetconf scope\&. From the NETCONF point of view, startup configuration data should be applied to the running datastore at this point\&. \fBncds_device_init()\fP can be used to perform this task, but applying running configuration data to the controlled device must be done by a server specific (non-libnetconf) function\&.
.IP "6." 4
\fBAccept incoming NETCONF connection\fP\&.
.br
This is done by a single call of \fBnc_session_accept()\fP or nc_session_Accept_username() alternatively\&. Optionally, any specific capabilities supported by the server can be set as the function's parameter\&.
.IP "7." 4
Server loop
.br
 Repeat these three steps:
.IP "  1." 6
\fBProcess incoming requests\fP\&.
.br
 Use \fBnc_session_recv_rpc()\fP to get the next request from the client from the specified NETCONF session\&. In case of an error return code, the state of the session should be checked by \fBnc_session_get_status()\fP to learn if the session can be further used\&.
.br
 According to the type of the request (\fBnc_rpc_get_type()\fP), perform an appropriate action:
.IP "    \(bu" 6
\fINC_RPC_DATASTORE_READ\fP or \fINC_RPC_DATASTORE_WRITE\fP: use \fBncds_apply_rpc2all()\fP to perform the requested operation on the datastore\&. If the request affects the running datastore (\fBnc_rpc_get_target()\fP returns NC_DATASTORE_RUNNING), apply configuration changes to the controlled device\&.
.IP "    \(bu" 6
\fINC_RPC_SESSION\fP: See the \fCNetopeer\fP example server source codes\&. There will be a common function added in the future to handle these requests\&.
.PP

.IP "  2." 6
\fBReply to the client's request\fP\&.
.br
 The reply message is automatically generated by the \fBncds_apply_rpc2all()\fP function\&. However, server can generate its own replies using \fBnc_reply_ok()\fP, \fBnc_reply_data()\fP (\fBnc_reply_data_ns()\fP) or \fBnc_reply_error()\fP functions\&. The reply is sent to the client using \fBnc_session_send_reply()\fP call\&.
.IP "  3." 6
\fBFree all unused objects\fP\&.
.br
 Do not forget to free received rpc messages (\fBnc_rpc_free()\fP) and any created replies (\fBnc_reply_free()\fP)\&.
.PP

.IP "8." 4
\fBClose the NETCONF session\fP\&.
.br
Use functions \fBnc_session_free()\fP to close and free all the used sources and structures connected with the session\&. Server should close the session when a nc_session_* function fails and libnetconf set the status of the session as non-working (nc_session_get_status != NC_SESSION_STATUS_WORKING)\&.
.IP "9." 4
\fBClose the libnetconf instance\fP
.br
Close internal libnetconf structures and subsystems by the \fBnc_close()\fP call\&. 
.PP

